package com.corgi.multi.anno.config;

import java.util.List;
import java.util.Map;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
   * @类名：         <p>DynamicDataSourceAspect</p>
   * @功能描述： <p>切面类，用于具体的数据源的动态切换</p>
   * @作者信息： <p>dengmiao</p>
   * @创建时间： <p>2018年5月6日下午1:01:45</p>
   * @修改备注：
 */
//@Aspect
@Order(-1)/**所有切面里面该切面优先执行*/
//@Component/**将类交给spring管理*/
public class DynamicDataSourceAspect {

	public static final Logger logger = LoggerFactory.getLogger(DynamicDataSourceAspect.class);
	
	/**
	 * 方法切入点
	 * 在调用具体业务逻辑之前，调用这个方法，切换数据源
	 * @param point
	 * @param ds
	 */
	@Before("@annotation(ds)")
	public void changeDataSource(JoinPoint point, TargetDataSource ds){
		String dsId = ds.value();
		Map<String, Integer> map = DynamicDataSourceContextHolder.getWeightMap();
		if("".equals(dsId.trim())){
			dsId = LoadBalance.WeightRandom(map);
			DynamicDataSourceContextHolder.setDataSource(dsId);
			logger.info(point + "进入负载均衡算法，当前切换的数据源是：{}",dsId);
		}else if(!DynamicDataSourceContextHolder.containsDataSource(dsId)){
			logger.error("数据源[{}]不存在",dsId);
		}else{
			DynamicDataSourceContextHolder.setDataSource(dsId);
			logger.info(point + "当前切换的数据源是：{}",dsId);
		}
	}
	
	/**
	 * 类切入点
	 * 在调用具体业务逻辑之前，调用这个方法，切换数据源
	 * @param point
	 */
//	@Before("execution(* com.westor.application.service..*.*(..))")
	public void changeDataSource(JoinPoint point){
		Signature sig = point.getSignature();
		String clazzName = sig.getDeclaringTypeName();
		String dsId = "";
		try {
			Class<?> clazz = DynamicDataSourceAspect.class.getClassLoader().loadClass(clazzName);
			TargetDataSource anno = (TargetDataSource) clazz.getAnnotation(TargetDataSource.class);
			//查找该clazz及其实现类是否被TargetDataSource所标记
			if(anno == null){
				List<Class<?>> list = ReflectHelper.getAllImplClassesByInterface(clazz);
				for(Class<?> claz : list){
					if(claz.isAnnotationPresent(TargetDataSource.class)){
						anno = (TargetDataSource) claz.getAnnotation(TargetDataSource.class);
						break;
					}
				}
			}
			if(anno != null){
				dsId = anno.value();
			}else{//进入方法切面
				return;
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		Map<String, Integer> map = DynamicDataSourceContextHolder.getWeightMap();
		if("".equals(dsId.trim())){
			dsId = LoadBalance.WeightRandom(map);
			DynamicDataSourceContextHolder.setDataSource(dsId);
			logger.info("进入负载均衡算法，当前切换的数据源是：{}",dsId);
		}else if(!DynamicDataSourceContextHolder.containsDataSource(dsId)){
//			logger.error("数据源[{}]不存在,",dsId);
		}else{
			logger.info("当前切换的数据源是：{}",dsId);
			DynamicDataSourceContextHolder.setDataSource(dsId);
		}
	}
}
